using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Linq;
using System.Windows.Forms;

namespace HslControls
{
	/// <summary>
	/// 一个高级的历史曲线的控件信息，适合用来显示不变的历史曲线，支持一些高级的操作功能
	/// </summary>
	[Description("历史曲线控件，支持光标移动，显示x,y轴数据信息，支持多条曲线，支持左右两个坐标轴")]
	[ToolboxBitmap(typeof(HslCurveHistory))]
	public class HslCurveHistory : UserControl
	{
		/// <summary>
		/// 基于时间的曲线双击的委托方法
		/// </summary>
		/// <param name="hslCurve">曲线控件信息</param>
		/// <param name="index">数据的索引</param>
		/// <param name="dateTime">时间信息</param>
		public delegate void CurveDoubleClick(HslCurveHistory hslCurve, int index, DateTime dateTime);

		/// <summary>
		/// 基于用户自定义的字符串的曲线双击的委托方法
		/// </summary>
		/// <param name="hslCurve">曲线控件信息</param>
		/// <param name="index">数据的索引</param>
		/// <param name="customer">时间信息</param>
		public delegate void CurveCustomerDoubleClick(HslCurveHistory hslCurve, int index, string customer);

		/// <summary>
		/// 当鼠标在曲线上移动的时候触发的委托方法
		/// </summary>
		/// <param name="hslCurve">曲线控件信息</param>
		/// <param name="x">横坐标x</param>
		/// <param name="y">横坐标y</param>
		public delegate void CurveMouseMove(HslCurveHistory hslCurve, int x, int y);

		/// <summary>
		/// 曲线的区间的委托签名
		/// </summary>
		/// <param name="hslCurve">曲线控件信息</param>
		/// <param name="index">数据的起始索引</param>
		/// <param name="end">数据的结束索引</param>
		public delegate void CurveRangeSelect(HslCurveHistory hslCurve, int index, int end);

		private List<AuxiliaryLable> auxiliary_Labels;

		private List<HslMarkLine> hslMarkLines;

		private List<HslMarkText> hslMarkTexts;

		private Dictionary<string, HslCurveItem> data_dicts = null;

		private List<HslCurveItem> data_lists = null;

		private List<DateTime> data_times = null;

		private List<string> data_customer = null;

		private List<AuxiliaryLine> auxiliary_lines;

		private float data_Scale_Render = 1f;

		private int data_count = 0;

		private string data_time_formate = "yyyy-MM-dd HH:mm:ss";

		private string mouse_hover_time_formate = "HH:mm:ss";

		private bool is_mouse_on_picture = false;

		private Point mouse_location = new Point(-1, -1);

		private int m_RowBetweenStart = -1;

		private int m_RowBetweenEnd = -1;

		private int m_RowBetweenStartHeight = -1;

		private int m_RowBetweenHeight = -1;

		private bool m_IsMouseLeftDown = false;

		private List<HslMarkBackSection> markBackSections = null;

		private List<HslMarkForeSection> markForeSections = null;

		private List<HslMarkForeSection> markForeSectionsTmp = null;

		private List<HslMarkForeSection> markForeActiveSections = null;

		private StringFormat sf = null;

		private StringFormat sf_left = null;

		private StringFormat sf_right = null;

		private StringFormat sf_default = null;

		private StringFormat sf_top = null;

		private Color backColor = Color.White;

		private Random random = null;

		private Color coordinateColor = Color.LightGray;

		private Brush coordinateBrush = new SolidBrush(Color.LightGray);

		private Pen coordinatePen = new Pen(Color.LightGray);

		private Color coordinateDashColor = Color.FromArgb(72, 72, 72);

		private Pen coordinateDashPen = null;

		private Color markLineColor = Color.Cyan;

		private Pen markLinePen = new Pen(Color.Cyan);

		private Color markTextColor = Color.Yellow;

		private Brush markTextBrush = new SolidBrush(Color.Yellow);

		private Color moveLineColor = Color.White;

		private Pen moveLinePen = new Pen(Color.White);

		private int data_tip_width = 150;

		private int curveNameWidth = 150;

		private int value_IntervalAbscissaText = 200;

		private float value_max_left = 100f;

		private float value_min_left = 0f;

		private float value_max_right = 100f;

		private float value_min_right = 0f;

		private string value_unit_left = string.Empty;

		private string value_unit_right = string.Empty;

		private int value_Segment = 5;

		private int pointsRadius = 0;

		private bool isShowTextInfomation = true;

		private bool isRederRightCoordinate = true;

		private bool isAllowSelectSection = true;

		private bool isRenderTimeData = false;

		private bool isMouseFreeze = false;

		private bool isAoordinateRoundInt = false;

		/// <summary> 
		/// 必需的设计器变量。
		/// </summary>
		private IContainer components = null;

		private PictureBox pictureBox3;

		private Panel panel1;

		/// <summary>
		/// 获取或设置控件的背景色
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置控件的背景色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "[46, 46, 46]")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		public override Color BackColor
		{
			get
			{
				return base.BackColor;
			}
			set
			{
				backColor = value;
				base.BackColor = value;
				if (isShowTextInfomation)
				{
					pictureBox3.Image?.Dispose();
					pictureBox3.Image = GetBitmapFromString(Text);
				}
			}
		}

		/// <summary>
		/// 获取或设置控件的背景色
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置控件的背景色")]
		[Category("HslControls")]
		[Bindable(true)]
		[DefaultValue(typeof(Color), "Yellow")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		public override Color ForeColor
		{
			get
			{
				return base.ForeColor;
			}
			set
			{
				base.ForeColor = value;
				if (isShowTextInfomation)
				{
					pictureBox3.Image?.Dispose();
					pictureBox3.Image = GetBitmapFromString(Text);
				}
			}
		}

		/// <summary>
		/// 获取或设置曲线控件是否显示右侧的坐标轴
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置曲线控件是否显示右侧的坐标轴")]
		[Category("HslControls")]
		[DefaultValue(true)]
		public bool RenderRightCoordinate
		{
			get
			{
				return isRederRightCoordinate;
			}
			set
			{
				isRederRightCoordinate = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置图形的纵坐标的最大值，该值必须大于最小值
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置图形的左纵坐标的最大值，该值必须大于最小值")]
		[Browsable(true)]
		[DefaultValue(100f)]
		public float ValueMaxLeft
		{
			get
			{
				return value_max_left;
			}
			set
			{
				if (value > value_min_left)
				{
					value_max_left = value;
					Invalidate();
				}
			}
		}

		/// <summary>
		/// 获取或设置图形的纵坐标的最小值，该值必须小于最大值
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置图形的左纵坐标的最小值，该值必须小于最大值")]
		[Browsable(true)]
		[DefaultValue(0f)]
		public float ValueMinLeft
		{
			get
			{
				return value_min_left;
			}
			set
			{
				if (value < value_max_left)
				{
					value_min_left = value;
					Invalidate();
				}
			}
		}

		/// <summary>
		/// 获取或设置图形的纵坐标的最大值，该值必须大于最小值
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置图形的右纵坐标的最大值，该值必须大于最小值")]
		[Browsable(true)]
		[DefaultValue(100f)]
		public float ValueMaxRight
		{
			get
			{
				return value_max_right;
			}
			set
			{
				if (value > value_min_right)
				{
					value_max_right = value;
					Invalidate();
				}
			}
		}

		/// <summary>
		/// 获取或设置图形的纵坐标的最小值，该值必须小于最大值
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置图形的右纵坐标的最小值，该值必须小于最大值")]
		[Browsable(true)]
		[DefaultValue(0f)]
		public float ValueMinRight
		{
			get
			{
				return value_min_right;
			}
			set
			{
				if (value < value_max_right)
				{
					value_min_right = value;
					Invalidate();
				}
			}
		}

		/// <summary>
		/// 获取或设置图形的纵轴分段数
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置图形的纵轴分段数")]
		[Browsable(true)]
		[DefaultValue(5)]
		public int ValueSegment
		{
			get
			{
				return value_Segment;
			}
			set
			{
				value_Segment = value;
				Invalidate();
				if (isShowTextInfomation)
				{
					pictureBox3.Image?.Dispose();
					pictureBox3.Image = GetBitmapFromString(Text);
				}
			}
		}

		/// <summary>
		/// 获取或设置当前控件的文本
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置当前控件的文本")]
		[Category("HslControls")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		[Bindable(true)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
		public override string Text
		{
			get
			{
				return base.Text;
			}
			set
			{
				isShowTextInfomation = true;
				base.Text = value;
				if (isShowTextInfomation)
				{
					pictureBox3.Image?.Dispose();
					pictureBox3.Image = GetBitmapFromString(Text);
				}
			}
		}

		/// <summary>
		/// 获取或设置左侧的单位显示的文本信息
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置左侧的单位显示的文本信息")]
		[Category("HslControls")]
		[DefaultValue("")]
		public string UnitLeft
		{
			get
			{
				return value_unit_left;
			}
			set
			{
				value_unit_left = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置右侧的单位显示的文本信息
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置右侧的单位显示的文本信息")]
		[Category("HslControls")]
		[DefaultValue("")]
		public string UnitRight
		{
			get
			{
				return value_unit_right;
			}
			set
			{
				value_unit_right = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 或者或设置所有的实线坐标轴的颜色
		/// </summary>
		[Browsable(true)]
		[Description("或者或设置所有的实线坐标轴的颜色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "LightGray")]
		public Color CoordinateColor
		{
			get
			{
				return coordinateColor;
			}
			set
			{
				coordinateColor = value;
				coordinatePen.Dispose();
				coordinatePen = new Pen(coordinateColor);
				coordinateBrush.Dispose();
				coordinateBrush = new SolidBrush(coordinateColor);
				Invalidate();
				if (isShowTextInfomation)
				{
					pictureBox3.Image?.Dispose();
					pictureBox3.Image = GetBitmapFromString(Text);
				}
			}
		}

		/// <summary>
		/// 或者或设置所有的虚线坐标轴的颜色
		/// </summary>
		[Browsable(true)]
		[Description("或者或设置所有的虚线坐标轴的颜色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "[72, 72, 72]")]
		public Color DashCoordinateColor
		{
			get
			{
				return coordinateDashColor;
			}
			set
			{
				coordinateDashColor = value;
				coordinateDashPen.Dispose();
				coordinateDashPen = new Pen(coordinateDashColor);
				coordinateDashPen.DashPattern = new float[2]
				{
					5f,
					5f
				};
				coordinateDashPen.DashStyle = DashStyle.Custom;
				Invalidate();
				if (isShowTextInfomation)
				{
					pictureBox3.Image?.Dispose();
					pictureBox3.Image = GetBitmapFromString(Text);
				}
			}
		}

		/// <summary>
		/// 或者或设置所有的区间标记的线条颜色
		/// </summary>
		[Browsable(true)]
		[Description("或者或设置所有的区间标记的线条颜色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "Cyan")]
		public Color MarkLineColor
		{
			get
			{
				return markLineColor;
			}
			set
			{
				markLineColor = value;
				markLinePen.Dispose();
				markLinePen = new Pen(markLineColor);
			}
		}

		/// <summary>
		/// 或者或设置所有的区间标记的文本颜色
		/// </summary>
		[Browsable(true)]
		[Description("或者或设置所有的区间标记的文本颜色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "Cyan")]
		public Color MarkTextColor
		{
			get
			{
				return markTextColor;
			}
			set
			{
				markTextColor = value;
				markTextBrush.Dispose();
				markTextBrush = new SolidBrush(markTextColor);
			}
		}

		/// <summary>
		/// 获取或设置鼠标移动过程中的提示线的颜色
		/// </summary>
		[Browsable(true)]
		[Description("或者或设置鼠标移动过程中的提示线的颜色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "White")]
		public Color MoveLineColor
		{
			get
			{
				return moveLineColor;
			}
			set
			{
				moveLineColor = value;
				moveLinePen.Dispose();
				moveLinePen = new Pen(moveLineColor);
			}
		}

		/// <summary>
		/// 获取或设置鼠标移动过程中提示信息的宽度
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置鼠标移动过程中提示信息的宽度")]
		[Category("HslControls")]
		[DefaultValue(150)]
		public int DataTipWidth
		{
			get
			{
				return data_tip_width;
			}
			set
			{
				if (value > 20 && value < 500)
				{
					data_tip_width = value;
				}
			}
		}

		/// <summary>
		/// 获取或设置曲线名称的布局宽度，默认为150
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置曲线名称的布局宽度，默认为150")]
		[Category("HslControls")]
		[DefaultValue(150)]
		public int CurveNameWidth
		{
			get
			{
				return curveNameWidth;
			}
			set
			{
				if (value > 10)
				{
					curveNameWidth = value;
				}
			}
		}

		/// <summary>
		/// 获取或设置纵向虚线的分隔情况，单位为多少个像素点
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置纵向虚线的分隔情况，单位为多少个像素点")]
		[Browsable(true)]
		[DefaultValue(200)]
		public int IntervalAbscissaText
		{
			get
			{
				return value_IntervalAbscissaText;
			}
			set
			{
				value_IntervalAbscissaText = value;
				Invalidate();
				if (isShowTextInfomation)
				{
					pictureBox3.Image?.Dispose();
					pictureBox3.Image = GetBitmapFromString(Text);
				}
			}
		}

		/// <summary>
		/// 获取或设置曲线图里所有的时间的格式，默认是 yyyy-MM-dd HH:mm:ss
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置曲线图里所有的时间的格式，默认是 yyyy-MM-dd HH:mm:ss")]
		[Browsable(true)]
		[DefaultValue("yyyy-MM-dd HH:mm:ss")]
		public string DateTimeFormate
		{
			get
			{
				return data_time_formate;
			}
			set
			{
				data_time_formate = value;
				Invalidate();
				if (isShowTextInfomation)
				{
					pictureBox3.Image?.Dispose();
					pictureBox3.Image = GetBitmapFromString(Text);
				}
			}
		}

		/// <summary>
		/// 获取或设置曲线图里光标移动时下方显示的时间格式，默认是HH:mm:ss
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置曲线图里光标移动时下方显示的时间格式，默认是HH:mm:ss")]
		[Browsable(true)]
		[DefaultValue("HH:mm:ss")]
		public string HoverDateTimeFormate
		{
			get
			{
				return mouse_hover_time_formate;
			}
			set
			{
				mouse_hover_time_formate = value;
			}
		}

		/// <summary>
		/// 获取或设置曲线是否禁止鼠标选择区间的功能。
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置曲线是否禁止鼠标选择区间的功能。")]
		[Browsable(true)]
		[DefaultValue(true)]
		public bool IsAllowSelectSection
		{
			get
			{
				return isAllowSelectSection;
			}
			set
			{
				isAllowSelectSection = value;
			}
		}

		/// <summary>
		/// 获取或设置纵轴是否强制使用整型
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置纵轴是否强制使用整型。")]
		[Browsable(true)]
		[DefaultValue(false)]
		public bool IsAoordinateRoundInt
		{
			get
			{
				return isAoordinateRoundInt;
			}
			set
			{
				isAoordinateRoundInt = value;
				Invalidate();
				if (isShowTextInfomation)
				{
					pictureBox3.Image?.Dispose();
					pictureBox3.Image = GetBitmapFromString(Text);
				}
			}
		}

		/// <summary>
		/// 获取或设置所有的数据点显示的半径大小，默认是0，不显示数据点
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置所有的数据点显示的半径大小，默认是0，不显示数据点")]
		[Category("HslControls")]
		[DefaultValue(0)]
		public int PointsRadius
		{
			get
			{
				return pointsRadius;
			}
			set
			{
				pointsRadius = value;
			}
		}

		/// <summary>
		/// 当鼠标在曲线上双击时触发，由此获取到点击的数据的索引位置，时间坐标
		/// </summary>
		[Category("Mouse")]
		[Description("当鼠标在曲线上双击时触发，由此获取到点击的数据的索引位置，时间坐标")]
		public event CurveDoubleClick onCurveDoubleClick;

		/// <summary>
		/// 当鼠标在曲线上双击时触发，由此获取到点击的数据的索引位置，用户自定义的坐标
		/// </summary>
		[Category("Mouse")]
		[Description("当鼠标在曲线上双击时触发，由此获取到点击的数据的索引位置，用户自定义的坐标")]
		public event CurveCustomerDoubleClick onCurveCustomerDoubleClick;

		/// <summary>
		/// 当鼠标在曲线上移动时触发，由此获取到鼠标的移动位置
		/// </summary>
		[Category("Mouse")]
		[Description("当鼠标在曲线上双击时触发，由此获取到鼠标的移动位置")]
		public event CurveMouseMove onCurveMouseMove;

		/// <summary>
		/// 当鼠标在曲线上双击时触发，由此获取到点击的数据的索引位置，时间坐标
		/// </summary>
		[Category("Mouse")]
		[Description("当鼠标在曲线上选择了一个区间，由此出发了一个选择事件，注意，包含两侧的端点。")]
		public event CurveRangeSelect onCurveRangeSelect;

		/// <summary>
		/// 实例化一个默认的历史曲线控件
		/// </summary>
		public HslCurveHistory()
		{
			auxiliary_lines = new List<AuxiliaryLine>();
			data_dicts = new Dictionary<string, HslCurveItem>();
			data_lists = new List<HslCurveItem>();
			markBackSections = new List<HslMarkBackSection>();
			markForeSections = new List<HslMarkForeSection>();
			markForeSectionsTmp = new List<HslMarkForeSection>();
			markForeActiveSections = new List<HslMarkForeSection>();
			hslMarkTexts = new List<HslMarkText>();
			hslMarkLines = new List<HslMarkLine>();
			auxiliary_Labels = new List<AuxiliaryLable>();
			data_times = new List<DateTime>(0);
			data_customer = new List<string>();
			sf_default = new StringFormat();
			sf = new StringFormat();
			sf.Alignment = StringAlignment.Center;
			sf.LineAlignment = StringAlignment.Center;
			sf_left = new StringFormat();
			sf_left.LineAlignment = StringAlignment.Center;
			sf_left.Alignment = StringAlignment.Near;
			sf_right = new StringFormat();
			sf_right.LineAlignment = StringAlignment.Center;
			sf_right.Alignment = StringAlignment.Far;
			sf_top = new StringFormat();
			sf_top.Alignment = StringAlignment.Center;
			sf_top.LineAlignment = StringAlignment.Near;
			coordinateDashPen = new Pen(Color.FromArgb(72, 72, 72));
			coordinateDashPen.DashPattern = new float[2]
			{
				5f,
				5f
			};
			coordinateDashPen.DashStyle = DashStyle.Custom;
			random = new Random();
			InitializeComponent();
			SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, value: true);
			SetStyle(ControlStyles.OptimizedDoubleBuffer, value: true);
			SetStyle(ControlStyles.AllPaintingInWmPaint, value: true);
			base.BackColor = Color.FromArgb(46, 46, 46);
			base.ForeColor = Color.Yellow;
		}

		private void HslCurveHistory_Load(object sender, EventArgs e)
		{
			if (isShowTextInfomation)
			{
				pictureBox3.Image?.Dispose();
				pictureBox3.Image = GetBitmapFromString(Text);
			}
			pictureBox3.MouseMove += PictureBox3_MouseMove;
			pictureBox3.MouseLeave += PictureBox3_MouseLeave;
			pictureBox3.MouseEnter += PictureBox3_MouseEnter;
			pictureBox3.MouseDown += PictureBox3_MouseDown;
			pictureBox3.MouseUp += PictureBox3_MouseUp;
			pictureBox3.Paint += PictureBox3_Paint;
			pictureBox3.MouseDoubleClick += PictureBox3_MouseDoubleClick;
			panel1.Scroll += Panel1_Scroll;
			base.MouseMove += HslCurveHistory_MouseMove;
			base.MouseDown += HslCurveHistory_MouseDown;
		}

		private void HslCurveHistory_MouseDown(object sender, MouseEventArgs e)
		{
			foreach (KeyValuePair<string, HslCurveItem> item in data_dicts)
			{
				if (item.Value.TitleRegion.Contains(e.Location))
				{
					item.Value.LineRenderVisiable = !item.Value.LineRenderVisiable;
					RenderCurveUI();
					break;
				}
			}
		}

		private void HslCurveHistory_MouseMove(object sender, MouseEventArgs e)
		{
			bool result = false;
			foreach (KeyValuePair<string, HslCurveItem> data_dict in data_dicts)
			{
				if (data_dict.Value.TitleRegion.Contains(e.Location))
				{
					result = true;
					break;
				}
			}
			Cursor = (result ? Cursors.Hand : Cursors.Arrow);
		}

		private void Panel1_Scroll(object sender, ScrollEventArgs e)
		{
			OnScroll(e);
		}

		/// <summary>
		/// 设置横向滚动条的位置信息
		/// </summary>
		/// <param name="e">位置信息</param>
		public void SetScrollPosition(ScrollEventArgs e)
		{
			panel1.HorizontalScroll.Value = e.NewValue;
		}

		/// <summary>
		/// 将曲线的滚动条设置到最右侧
		/// </summary>
		public void ScrollToRight()
		{
			panel1.HorizontalScroll.Value = panel1.HorizontalScroll.Maximum - 1;
			panel1.HorizontalScroll.Value = panel1.HorizontalScroll.Maximum - 1;
		}

		private void DrawCoordinate(Graphics g, bool isLeft, float dx, float dy, float value_max, float value_min, StringFormat stringFormat, string unit)
		{
			g.TranslateTransform(dx, dy);
			float m_height = base.Height - 29 - 3;
			float m_width = 40f;
			if (isLeft)
			{
				g.DrawLine(coordinatePen, m_width - 1f, 5f, m_width - 1f, m_height - 35f);
			}
			else
			{
				g.DrawLine(coordinatePen, 0f, 5f, 0f, m_height - 35f);
			}
			if (isLeft)
			{
				HslHelper.PaintTriangle(g, coordinateBrush, new PointF(m_width - 1f, 10f), 5, GraphDirection.Upward);
			}
			else
			{
				HslHelper.PaintTriangle(g, coordinateBrush, new PointF(0f, 10f), 5, GraphDirection.Upward);
			}
			g.DrawString(unit, Font, coordinateBrush, new RectangleF(0f, -15f, m_width, 30f), sf);
			for (int j = 0; j <= value_Segment; j++)
			{
				float valueTmpLeft = (float)((double)j * (double)(value_max - value_min) / (double)value_Segment + (double)value_min);
				if (IsAoordinateRoundInt)
				{
					valueTmpLeft = (float)Math.Round(valueTmpLeft, 0);
				}
				float paintTmp = HslHelper.ComputePaintLocationY(value_max, value_min, m_height - 60f, valueTmpLeft) + 20f;
				if (IsNeedPaintDash(paintTmp))
				{
					if (isLeft)
					{
						g.DrawLine(coordinatePen, m_width - 5f, paintTmp, m_width - 2f, paintTmp);
						g.DrawString(layoutRectangle: new RectangleF(0f, paintTmp - 9f, m_width - 4f, 20f), s: valueTmpLeft.ToString(), font: Font, brush: coordinateBrush, format: stringFormat);
					}
					else
					{
						g.DrawLine(coordinatePen, 1f, paintTmp, 5f, paintTmp);
						g.DrawString(layoutRectangle: new RectangleF(5f, paintTmp - 9f, m_width - 3f, 20f), s: valueTmpLeft.ToString(), font: Font, brush: coordinateBrush, format: stringFormat);
					}
				}
			}
			for (int i = 0; i < auxiliary_lines.Count; i++)
			{
				if (auxiliary_lines[i].IsLeftFrame)
				{
					float paintTmp2 = HslHelper.ComputePaintLocationY(value_max, value_min, m_height - 60f, auxiliary_lines[i].Value) + 20f;
					if (isLeft)
					{
						g.DrawLine(coordinatePen, m_width - 5f, paintTmp2, m_width - 2f, paintTmp2);
						g.DrawString(layoutRectangle: new RectangleF(0f, paintTmp2 - 9f, m_width - 4f, 20f), s: auxiliary_lines[i].Value.ToString(), font: Font, brush: coordinateBrush, format: stringFormat);
					}
					else
					{
						g.DrawLine(coordinatePen, 1f, paintTmp2, 5f, paintTmp2);
						g.DrawString(layoutRectangle: new RectangleF(6f, paintTmp2 - 9f, m_width - 3f, 20f), s: auxiliary_lines[i].Value.ToString(), font: Font, brush: coordinateBrush, format: stringFormat);
					}
				}
			}
			g.TranslateTransform(0f - dx, 0f - dy);
		}

		private Bitmap GetBitmapFromString(string text)
		{
			int m_width = (panel1.Width <= 10) ? 1 : panel1.Width;
			int m_height = (panel1.Height > 10) ? panel1.Height : 10;
			Bitmap bitmap = new Bitmap(m_width, m_height);
			Graphics g = Graphics.FromImage(bitmap);
			g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
			g.SmoothingMode = SmoothingMode.HighQuality;
			g.Clear(backColor);
			PaintFromString(g, text, m_width, m_height);
			g.Dispose();
			return bitmap;
		}

		private void PaintFromString(Graphics g, string text, int m_width, int m_height)
		{
			Font font = new Font(Font.FontFamily, 18f);
			if (text != null && text.Length > 400)
			{
				font = new Font(Font.FontFamily, 12f);
			}
			int m_Paint_Height = m_height - 60;
			g.DrawLine(coordinatePen, 0, m_height - 40, m_width - 1, m_height - 40);
			for (int k = 1; k <= value_Segment; k++)
			{
				float valueTmpLeft = (float)((double)k * (double)(value_max_left - value_min_left) / (double)value_Segment + (double)value_min_left);
				float paintTmp = HslHelper.ComputePaintLocationY(value_max_left, value_min_left, m_height - 60, valueTmpLeft) + 20f;
				if (IsNeedPaintDash(paintTmp))
				{
					g.DrawLine(coordinateDashPen, 0f, paintTmp, m_width - 1, paintTmp);
				}
			}
			CalculateAuxiliaryPaintY();
			for (int j = 0; j < auxiliary_lines.Count; j++)
			{
				g.DrawLine(auxiliary_lines[j].GetPen(), 0f, auxiliary_lines[j].PaintValue, m_width - 1, auxiliary_lines[j].PaintValue);
			}
			for (int i = value_IntervalAbscissaText; i < m_width; i += value_IntervalAbscissaText)
			{
				g.DrawLine(coordinateDashPen, i, m_height - 40, i, 0);
			}
			Rectangle m_rect = new Rectangle(0, 0, m_width, m_height);
			using (Brush brush = new SolidBrush(ForeColor))
			{
				g.DrawString(text, font, brush, m_rect, sf);
			}
			font.Dispose();
		}

		private bool IsNeedPaintDash(float paintValue)
		{
			for (int i = 0; i < auxiliary_lines.Count; i++)
			{
				if (Math.Abs(auxiliary_lines[i].PaintValue - paintValue) < (float)Font.Height)
				{
					return false;
				}
			}
			return true;
		}

		/// <summary>
		/// 控件的重绘信息
		/// </summary>
		/// <param name="e">重绘的方法</param>
		protected override void OnPaint(PaintEventArgs e)
		{
			if (Authorization.iashdiadasbdnajsdhjaf())
			{
				Graphics g = e.Graphics;
				g.SmoothingMode = SmoothingMode.HighQuality;
				g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
				PaintMain(g, base.Width, base.Height);
				base.OnPaint(e);
			}
		}

		private void PaintMain(Graphics g, float width, float height)
		{
			DrawCoordinate(g, isLeft: true, 3f, 29f, value_max_left, value_min_left, sf_right, value_unit_left);
			if (isRederRightCoordinate)
			{
				DrawCoordinate(g, isLeft: false, base.Width - 43, 29f, value_max_right, value_min_right, sf_left, value_unit_right);
			}
			PaintHeadText(g);
		}

		private void PaintHeadText(Graphics g)
		{
			float x_start = 50f;
			foreach (KeyValuePair<string, HslCurveItem> item in data_dicts)
			{
				if (item.Value.Visible)
				{
					Pen pen = item.Value.LineRenderVisiable ? new Pen(item.Value.LineColor) : new Pen(Color.FromArgb(80, item.Value.LineColor));
					g.DrawLine(pen, x_start, 11f, x_start + 30f, 11f);
					g.DrawEllipse(pen, x_start + 8f, 4f, 14f, 14f);
					pen.Dispose();
					SolidBrush textBrush = item.Value.LineRenderVisiable ? new SolidBrush(item.Value.LineColor) : new SolidBrush(Color.FromArgb(80, item.Value.LineColor));
					g.DrawString(item.Key, Font, textBrush, new RectangleF(x_start + 35f, 2f, curveNameWidth - 30, 18f), sf_left);
					item.Value.TitleRegion = new RectangleF(x_start, 2f, 60f, 18f);
					textBrush.Dispose();
					x_start += (float)curveNameWidth;
				}
			}
			for (int i = 0; i < auxiliary_Labels.Count; i++)
			{
				if (!string.IsNullOrEmpty(auxiliary_Labels[i].Text))
				{
					int start = (auxiliary_Labels[i].LocationX > 1f) ? ((int)auxiliary_Labels[i].LocationX) : ((int)(auxiliary_Labels[i].LocationX * (float)panel1.Width));
					int labelWidth = (int)g.MeasureString(auxiliary_Labels[i].Text, Font).Width + 3;
					Point[] labelBounds = new Point[6]
					{
						new Point(start, 11),
						new Point(start + 10, 20),
						new Point(start + labelWidth + 10, 20),
						new Point(start + labelWidth + 10, 0),
						new Point(start + 10, 0),
						new Point(start, 11)
					};
					g.FillPolygon(auxiliary_Labels[i].TextBack, labelBounds);
					g.DrawString(auxiliary_Labels[i].Text, Font, auxiliary_Labels[i].TextBrush, new Rectangle(start + 7, 0, labelWidth + 3, 20), sf);
				}
			}
		}

		private void HslCurveHistory_SizeChanged(object sender, EventArgs e)
		{
			if (isShowTextInfomation)
			{
				pictureBox3.Image?.Dispose();
				pictureBox3.Image = GetBitmapFromString(Text);
				Invalidate();
			}
			else
			{
				RenderCurveUI();
			}
		}

		/// <summary>
		/// 引发controls的dock的变化
		/// </summary>
		/// <param name="e">事件消息</param>
		protected override void OnDockChanged(EventArgs e)
		{
			base.OnDockChanged(e);
			HslCurveHistory_SizeChanged(this, e);
		}

		/// <summary>
		/// 计算所有的辅助线的缓存的文本信息，在界面大小变化的时候，需要重新计算
		/// </summary>
		private void CalculateAuxiliaryPaintY()
		{
			for (int i = 0; i < auxiliary_lines.Count; i++)
			{
				if (auxiliary_lines[i].IsLeftFrame)
				{
					auxiliary_lines[i].PaintValue = HslHelper.ComputePaintLocationY(value_max_left, value_min_left, panel1.Height - 60, auxiliary_lines[i].Value) + 20f;
				}
				else
				{
					auxiliary_lines[i].PaintValue = HslHelper.ComputePaintLocationY(value_max_right, value_min_right, panel1.Height - 60, auxiliary_lines[i].Value) + 20f;
				}
			}
		}

		/// <summary>
		/// 新增一条左侧的辅助线，使用默认的文本颜色
		/// </summary>
		/// <param name="value">数据值</param>
		public void AddLeftAuxiliary(float value)
		{
			AddLeftAuxiliary(value, coordinateColor);
		}

		/// <summary>
		/// 新增一条左侧的辅助线，使用指定的颜色
		/// </summary>
		/// <param name="value">数据值</param>
		/// <param name="lineColor">线条颜色</param>
		public void AddLeftAuxiliary(float value, Color lineColor)
		{
			AddLeftAuxiliary(value, lineColor, 1f, isDashLine: true);
		}

		/// <summary>
		/// 新增一条左侧的辅助线
		/// </summary>
		/// <param name="value">数据值</param>
		/// <param name="lineColor">线条颜色</param>
		/// <param name="lineThickness">线条宽度</param>
		/// <param name="isDashLine">是否是虚线</param>
		public void AddLeftAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine)
		{
			AddAuxiliary(value, lineColor, lineThickness, isDashLine, isLeft: true);
		}

		/// <summary>
		/// 新增一条右侧的辅助线，使用默认的文本颜色
		/// </summary>
		/// <param name="value">数据值</param>
		public void AddRightAuxiliary(float value)
		{
			AddRightAuxiliary(value, coordinateColor);
		}

		/// <summary>
		/// 新增一条右侧的辅助线，使用指定的颜色
		/// </summary>
		/// <param name="value">数据值</param>
		/// <param name="lineColor">线条颜色</param>
		public void AddRightAuxiliary(float value, Color lineColor)
		{
			AddRightAuxiliary(value, lineColor, 1f, isDashLine: true);
		}

		/// <summary>
		/// 新增一条右侧的辅助线
		/// </summary>
		/// <param name="value">数据值</param>
		/// <param name="lineColor">线条颜色</param>
		/// <param name="lineThickness">线条宽度</param>
		/// <param name="isDashLine">是否是虚线的信息</param>
		public void AddRightAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine)
		{
			AddAuxiliary(value, lineColor, lineThickness, isDashLine, isLeft: false);
		}

		private void AddAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine, bool isLeft)
		{
			auxiliary_lines.Add(new AuxiliaryLine
			{
				Value = value,
				LineColor = lineColor,
				PenDash = new Pen(lineColor)
				{
					DashStyle = DashStyle.Custom,
					DashPattern = new float[2]
					{
						5f,
						5f
					}
				},
				PenSolid = new Pen(lineColor),
				IsDashStyle = isDashLine,
				IsLeftFrame = isLeft,
				LineThickness = lineThickness,
				LineTextBrush = new SolidBrush(lineColor)
			});
			CalculateAuxiliaryPaintY();
			if (isShowTextInfomation)
			{
				pictureBox3.Image?.Dispose();
				pictureBox3.Image = GetBitmapFromString(Text);
			}
		}

		/// <summary>
		/// 移除所有的指定值的辅助曲线，包括左边的和右边的
		/// </summary>
		/// <param name="value"></param>
		public void RemoveAuxiliary(float value)
		{
			int removeCount = 0;
			for (int i = auxiliary_lines.Count - 1; i >= 0; i--)
			{
				if (auxiliary_lines[i].Value == value)
				{
					auxiliary_lines[i].Dispose();
					auxiliary_lines.RemoveAt(i);
					removeCount++;
				}
			}
			if (removeCount > 0)
			{
				Invalidate();
			}
		}

		/// <summary>
		/// 移除所有的辅助线
		/// </summary>
		public void RemoveAllAuxiliary()
		{
			int removeCount = auxiliary_lines.Count;
			auxiliary_lines.Clear();
			if (removeCount > 0)
			{
				Invalidate();
			}
		}

		/// <summary>
		/// 新增一条辅助标签
		/// </summary>
		/// <param name="auxiliaryLable">描述的标签值</param>
		public void AddAuxiliaryLabel(AuxiliaryLable auxiliaryLable)
		{
			auxiliary_Labels.Add(auxiliaryLable);
		}

		/// <summary>
		/// 移除指定的辅助标签
		/// </summary>
		/// <param name="auxiliaryLable">等待删除的对象</param>
		public void RemoveAuxiliaryLable(AuxiliaryLable auxiliaryLable)
		{
			if (auxiliary_Labels.Remove(auxiliaryLable))
			{
				Invalidate();
			}
		}

		/// <summary>
		/// 移除所有的辅助标签
		/// </summary>
		public void RemoveAllAuxiliaryLable()
		{
			int removeCount = auxiliary_Labels.Count;
			auxiliary_Labels.Clear();
			if (removeCount > 0)
			{
				Invalidate();
			}
		}

		/// <summary>
		/// 新增一个标记的线段信息
		/// </summary>
		/// <param name="markLine">线段标记信息</param>
		public void AddMarkLine(HslMarkLine markLine)
		{
			hslMarkLines.Add(markLine);
		}

		/// <summary>
		/// 移除一个标记的线段信息
		/// </summary>
		/// <param name="markLine">线段标记信息</param>
		public void RemoveMarkLine(HslMarkLine markLine)
		{
			hslMarkLines.Remove(markLine);
		}

		/// <summary>
		/// 移除所有的标记的线段信息
		/// </summary>
		public void RemoveAllMarkLine()
		{
			hslMarkLines.Clear();
		}

		/// <summary>
		/// 新增一个标记的文本信息
		/// </summary>
		/// <param name="markText">文本标记信息</param>
		public void AddMarkText(HslMarkText markText)
		{
			hslMarkTexts.Add(markText);
		}

		/// <summary>
		/// 移除一个标记的文本信息
		/// </summary>
		/// <param name="markText">文本标记信息</param>
		public void RemoveMarkText(HslMarkText markText)
		{
			hslMarkTexts.Remove(markText);
		}

		/// <summary>
		/// 移除所有的标记的文本信息
		/// </summary>
		public void RemoveAllMarkText()
		{
			hslMarkTexts.Clear();
		}

		private void CalculateCurveDataMax()
		{
			data_count = 0;
			for (int i = 0; i < data_lists.Count; i++)
			{
				if (data_count < data_lists[i].Data.Length)
				{
					data_count = data_lists[i].Data.Length;
				}
			}
		}

		/// <summary>
		/// 设置系统横轴的显示坐标信息
		/// </summary>
		/// <param name="times">时间数组</param>
		public void SetDateTimes(DateTime[] times)
		{
			data_times = new List<DateTime>(times);
			isRenderTimeData = true;
		}

		/// <summary>
		/// 设置系统横轴的显示坐标信息
		/// </summary>
		/// <param name="customers">自定义的数组</param>
		public void SetDateCustomer(string[] customers)
		{
			data_customer = new List<string>(customers);
			isRenderTimeData = false;
		}

		/// <summary>
		/// 设置当前曲线的横轴的缩放等级，必须大于0，小于1则为缩放，大于1则为放大
		/// </summary>
		/// <param name="scale">缩放等级，必须大于0，小于1则为缩放，大于1则为放大</param>
		public void SetScaleByXAxis(float scale)
		{
			data_Scale_Render = scale;
		}

		/// <summary>
		/// 新增或修改一条指定关键字的左参考系曲线数据，需要指定数据，颜色随机，没有数据上限，线条宽度为1
		/// </summary>
		/// <param name="key">曲线关键字</param>
		/// <param name="data">曲线的具体数据</param>
		public void SetLeftCurve(string key, float[] data)
		{
			SetLeftCurve(key, data, Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)));
		}

		/// <summary>
		/// 新增或修改一条指定关键字的左参考系曲线数据，需要指定数据，颜色，没有数据上限，线条宽度为1
		/// </summary>
		/// <param name="key">曲线关键字</param>
		/// <param name="data">数据内容</param>
		/// <param name="lineColor">曲线颜色</param>
		public void SetLeftCurve(string key, float[] data, Color lineColor)
		{
			SetCurve(key, isLeft: true, data, lineColor, 1f, CurveStyle.LineSegment);
		}

		/// <summary>
		/// 新增或修改一条指定关键字的左参考系曲线数据，需要指定数据，颜色，没有数据上限，线条宽度为1
		/// </summary>
		/// <param name="key">曲线关键字</param>
		/// <param name="data">数据内容</param>
		/// <param name="lineColor">曲线颜色</param>
		/// <param name="style">曲线的样式</param>
		public void SetLeftCurve(string key, float[] data, Color lineColor, CurveStyle style)
		{
			SetCurve(key, isLeft: true, data, lineColor, 1f, style);
		}

		/// <summary>
		/// 新增或修改一条指定关键字的左参考系曲线数据，需要指定数据，颜色，没有数据上限，线条宽度为1
		/// </summary>
		/// <param name="key">曲线关键字</param>
		/// <param name="data">数据内容</param>
		/// <param name="lineColor">曲线颜色</param>
		/// <param name="style">曲线的样式</param>
		/// <param name="renderFormat">数据显示的格式化操作</param>
		public void SetLeftCurve(string key, float[] data, Color lineColor, CurveStyle style, string renderFormat)
		{
			SetCurve(key, isLeft: true, data, lineColor, 1f, style, renderFormat);
		}

		/// <summary>
		/// 新增或修改一条指定关键字的右参考系曲线数据，需要指定数据，颜色随机，没有数据上限，线条宽度为1
		/// </summary>
		/// <param name="key">曲线关键字</param>
		/// <param name="data">数据内容</param>
		public void SetRightCurve(string key, float[] data)
		{
			SetRightCurve(key, data, Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)));
		}

		/// <summary>
		/// 新增或修改一条指定关键字的右参考系曲线数据，需要指定数据，颜色，没有数据上限，线条宽度为1
		/// </summary>
		/// <param name="key">曲线关键字</param>
		/// <param name="data">数据内容</param>
		/// <param name="lineColor">曲线颜色</param>
		public void SetRightCurve(string key, float[] data, Color lineColor)
		{
			SetCurve(key, isLeft: false, data, lineColor, 1f, CurveStyle.LineSegment);
		}

		/// <summary>
		/// 新增或修改一条指定关键字的右参考系曲线数据，需要指定数据，颜色，没有数据上限，线条宽度为1
		/// </summary>
		/// <param name="key">曲线关键字</param>
		/// <param name="data">数据内容</param>
		/// <param name="lineColor">曲线颜色</param>
		/// <param name="style">曲线的样式</param>
		public void SetRightCurve(string key, float[] data, Color lineColor, CurveStyle style)
		{
			SetCurve(key, isLeft: false, data, lineColor, 1f, style);
		}

		/// <summary>
		/// 新增或修改一条指定关键字的右参考系曲线数据，需要指定数据，颜色，没有数据上限，线条宽度为1
		/// </summary>
		/// <param name="key">曲线关键字</param>
		/// <param name="data">数据内容</param>
		/// <param name="lineColor">曲线颜色</param>
		/// <param name="style">曲线的样式</param>
		/// <param name="renderFormat">数据显示的格式化操作</param>
		public void SetRightCurve(string key, float[] data, Color lineColor, CurveStyle style, string renderFormat)
		{
			SetCurve(key, isLeft: false, data, lineColor, 1f, style, renderFormat);
		}

		/// <summary>
		/// 新增或修改一条指定关键字的曲线数据，需要指定参考系及数据，颜色，线条宽度
		/// </summary>
		/// <param name="key">曲线关键字</param>
		/// <param name="isLeft">是否以左侧坐标轴为参照系</param>
		/// <param name="data">数据</param>
		/// <param name="lineColor">线条颜色</param>
		/// <param name="thickness">线条宽度</param>
		/// <param name="style">曲线的样式</param>
		public void SetCurve(string key, bool isLeft, float[] data, Color lineColor, float thickness, CurveStyle style)
		{
			SetCurve(key, isLeft, data, lineColor, thickness, style, "{0}");
		}

		/// <summary>
		/// 新增或修改一条指定关键字的曲线数据，需要指定参考系及数据，颜色，线条宽度
		/// </summary>
		/// <param name="key">曲线关键字</param>
		/// <param name="isLeft">是否以左侧坐标轴为参照系</param>
		/// <param name="data">数据</param>
		/// <param name="lineColor">线条颜色</param>
		/// <param name="thickness">线条宽度</param>
		/// <param name="style">曲线的样式</param>
		/// <param name="renderFormat">数据显示的格式化操作</param>
		public void SetCurve(string key, bool isLeft, float[] data, Color lineColor, float thickness, CurveStyle style, string renderFormat)
		{
			if (data_dicts.ContainsKey(key))
			{
				if (data == null)
				{
					data = new float[0];
				}
				data_dicts[key].Data = data;
			}
			else
			{
				if (data == null)
				{
					data = new float[0];
				}
				data_dicts.Add(key, new HslCurveItem
				{
					Data = data,
					LineThickness = thickness,
					LineColor = lineColor,
					IsLeftFrame = isLeft,
					Style = style,
					RenderFormat = renderFormat
				});
				data_lists.Add(data_dicts[key]);
			}
			CalculateCurveDataMax();
		}

		/// <summary>
		/// 移除指定关键字的曲线
		/// </summary>
		/// <param name="key">曲线关键字</param>
		public void RemoveCurve(string key)
		{
			if (data_dicts.ContainsKey(key))
			{
				data_lists.Remove(data_dicts[key]);
				data_dicts.Remove(key);
			}
			if (data_dicts.Count == 0)
			{
				data_times = new List<DateTime>(0);
				data_customer = new List<string>();
			}
			CalculateCurveDataMax();
		}

		/// <summary>
		/// 移除指定关键字的曲线，包含了所有的特殊标记信息
		/// </summary>
		public void RemoveAllCurve()
		{
			data_dicts.Clear();
			data_lists.Clear();
			markBackSections.Clear();
			markForeSections.Clear();
			markForeSectionsTmp.Clear();
			markForeActiveSections.Clear();
			hslMarkTexts.Clear();
			auxiliary_Labels.Clear();
			hslMarkLines.Clear();
			if (data_dicts.Count == 0)
			{
				data_times = new List<DateTime>(0);
			}
			CalculateCurveDataMax();
		}

		/// <summary>
		/// 设置一条曲线是否是可见的，如果该曲线不存在，则无效。
		/// </summary>
		/// <param name="key">关键字</param>
		/// <param name="visible">是否可见</param>
		public void SetCurveVisible(string key, bool visible)
		{
			if (data_dicts.ContainsKey(key))
			{
				HslCurveItem curve = data_dicts[key];
				curve.Visible = visible;
			}
		}

		/// <summary>
		/// 设置多条曲线是否是可见的，如果该曲线不存在，则无效。
		/// </summary>
		/// <param name="keys">关键字</param>
		/// <param name="visible">是否可见</param>
		public void SetCurveVisible(string[] keys, bool visible)
		{
			foreach (string key in keys)
			{
				if (data_dicts.ContainsKey(key))
				{
					HslCurveItem curve = data_dicts[key];
					curve.Visible = visible;
				}
			}
		}

		/// <summary>
		/// 更新整个的界面显示
		/// </summary>
		public void RenderCurveUI()
		{
			int m_width = (int)((float)data_count * data_Scale_Render) + 200;
			if (m_width < panel1.Width)
			{
				m_width = panel1.Width;
			}
			int m_height = panel1.Height - 18;
			if (m_height < 10)
			{
				m_height = 10;
			}
			Bitmap bitmap = new Bitmap(m_width, m_height);
			Graphics g = Graphics.FromImage(bitmap);
			g.SmoothingMode = SmoothingMode.AntiAlias;
			g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
			g.Clear(backColor);
			GetRenderCurveMain(g, m_width, m_height);
			g.Dispose();
			pictureBox3.Image?.Dispose();
			pictureBox3.Image = bitmap;
			Invalidate();
			isShowTextInfomation = false;
		}

		private void GetRenderCurveMain(Graphics g, int m_width, int m_height)
		{
			for (int i = 0; i < markBackSections.Count; i++)
			{
				RectangleF rect = new RectangleF((float)markBackSections[i].StartIndex * data_Scale_Render, 0f, (float)(markBackSections[i].EndIndex - markBackSections[i].StartIndex) * data_Scale_Render, panel1.Height - 60 + 20);
				using (Brush brush = new SolidBrush(markBackSections[i].BackColor))
				{
					g.FillRectangle(brush, rect);
				}
				g.DrawRectangle(Pens.DimGray, rect.X, rect.Y, rect.Width, rect.Height);
				string text = markBackSections[i].MarkText ?? string.Empty;
				if (markBackSections[i].StartIndex < data_times.Count && markBackSections[i].EndIndex < data_times.Count)
				{
					text = text + " (" + (data_times[markBackSections[i].EndIndex] - data_times[markBackSections[i].StartIndex]).TotalMinutes.ToString("F1") + " 分钟)";
				}
				g.DrawString(text, Font, Brushes.DimGray, new RectangleF(rect.X, 3f, rect.Width, panel1.Height - 60), sf_top);
			}
			g.DrawLine(coordinatePen, 0, panel1.Height - 40, m_width - 1, panel1.Height - 40);
			CalculateAuxiliaryPaintY();
			for (int j = 1; j <= value_Segment; j++)
			{
				float valueTmpLeft = (float)((double)j * (double)(value_max_left - value_min_left) / (double)value_Segment + (double)value_min_left);
				if (IsAoordinateRoundInt)
				{
					valueTmpLeft = (float)Math.Round(valueTmpLeft, 0);
				}
				float paintTmp = HslHelper.ComputePaintLocationY(value_max_left, value_min_left, panel1.Height - 60, valueTmpLeft) + 20f;
				if (IsNeedPaintDash(paintTmp))
				{
					g.DrawLine(coordinateDashPen, 0f, paintTmp, m_width - 1, paintTmp);
				}
			}
			for (int k = 0; k < auxiliary_lines.Count; k++)
			{
				g.DrawLine(auxiliary_lines[k].GetPen(), 0f, auxiliary_lines[k].PaintValue, m_width - 1, auxiliary_lines[k].PaintValue);
			}
			for (int l = value_IntervalAbscissaText; l < m_width; l += value_IntervalAbscissaText)
			{
				int index = Convert.ToInt32((float)l / data_Scale_Render);
				g.DrawLine(coordinateDashPen, l, panel1.Height - 38, l, 0);
				if (isRenderTimeData)
				{
					if (index < data_times.Count)
					{
						g.DrawString(data_times[index].ToString(data_time_formate), Font, coordinateBrush, new Rectangle(l - 100, panel1.Height - 40, 200, 22), sf);
					}
				}
				else if (index < data_customer.Count)
				{
					g.DrawString(data_customer[index], Font, coordinateBrush, new Rectangle(l - 100, panel1.Height - 40, 200, 22), sf);
				}
			}
			foreach (HslMarkText markText in hslMarkTexts)
			{
				foreach (KeyValuePair<string, HslCurveItem> line in data_dicts)
				{
					if (!line.Value.Visible || !line.Value.LineRenderVisiable || line.Key != markText.CurveKey)
					{
						continue;
					}
					float[] data = line.Value.Data;
					if (data != null && data.Length > 1 && markText.Index >= 0 && markText.Index < line.Value.Data.Length && !float.IsNaN(line.Value.Data[markText.Index]))
					{
						PointF center = new PointF((float)markText.Index * data_Scale_Render, HslHelper.ComputePaintLocationY(line.Value.IsLeftFrame ? value_max_left : value_max_right, line.Value.IsLeftFrame ? value_min_left : value_min_right, panel1.Height - 60, line.Value.Data[markText.Index]) + 20f);
						g.FillEllipse(markText.CircleBrush, new RectangleF(center.X - 3f, center.Y - 3f, 6f, 6f));
						switch ((markText.PositionStyle == MarkTextPositionStyle.Auto) ? HslMarkText.CalculateDirectionFromDataIndex(line.Value.Data, markText.Index) : markText.PositionStyle)
						{
						case MarkTextPositionStyle.Left:
							g.DrawString(markText.MarkText, Font, markText.TextBrush, new RectangleF(center.X - 100f, center.Y - (float)Font.Height, 100 - HslMarkText.MarkTextOffect, Font.Height * 2), sf_right);
							break;
						case MarkTextPositionStyle.Up:
							g.DrawString(markText.MarkText, Font, markText.TextBrush, new RectangleF(center.X - 100f, center.Y - (float)Font.Height - (float)HslMarkText.MarkTextOffect, 200f, Font.Height + 2), sf);
							break;
						case MarkTextPositionStyle.Right:
							g.DrawString(markText.MarkText, Font, markText.TextBrush, new RectangleF(center.X + (float)HslMarkText.MarkTextOffect, center.Y - (float)Font.Height, 100f, Font.Height * 2), sf_left);
							break;
						case MarkTextPositionStyle.Down:
							g.DrawString(markText.MarkText, Font, markText.TextBrush, new RectangleF(center.X - 100f, center.Y + (float)HslMarkText.MarkTextOffect, 200f, Font.Height + 2), sf);
							break;
						}
					}
				}
			}
			foreach (HslMarkLine markLine in hslMarkLines)
			{
				PointF[] points2 = markLine.Points;
				if (points2 == null || points2.Length <= 1)
				{
					continue;
				}
				PointF[] points = new PointF[markLine.Points.Length];
				for (int i3 = 0; i3 < markLine.Points.Length; i3++)
				{
					points[i3].X = markLine.Points[i3].X * data_Scale_Render;
					points[i3].Y = HslHelper.ComputePaintLocationY(markLine.IsLeftFrame ? value_max_left : value_max_right, markLine.IsLeftFrame ? value_min_left : value_min_right, panel1.Height - 60, markLine.Points[i3].Y) + 20f;
					g.FillEllipse(markLine.CircleBrush, new RectangleF(points[i3].X - 3f, points[i3].Y - 3f, 6f, 6f));
					MarkTextPositionStyle markTextPosition = HslMarkText.CalculateDirectionFromDataIndex(markLine.Points.Select((PointF m) => m.Y).ToArray(), i3);
					if (markLine.Marks != null)
					{
						switch (markTextPosition)
						{
						case MarkTextPositionStyle.Left:
							g.DrawString(markLine.Marks[i3], Font, markLine.TextBrush, new RectangleF(points[i3].X - 100f, points[i3].Y - (float)Font.Height, 100 - HslMarkText.MarkTextOffect, Font.Height * 2), sf_right);
							break;
						case MarkTextPositionStyle.Up:
							g.DrawString(markLine.Marks[i3], Font, markLine.TextBrush, new RectangleF(points[i3].X - 100f, points[i3].Y - (float)Font.Height - (float)HslMarkText.MarkTextOffect, 200f, Font.Height + 2), sf);
							break;
						case MarkTextPositionStyle.Right:
							g.DrawString(markLine.Marks[i3], Font, markLine.TextBrush, new RectangleF(points[i3].X + (float)HslMarkText.MarkTextOffect, points[i3].Y - (float)Font.Height, 100f, Font.Height * 2), sf_left);
							break;
						case MarkTextPositionStyle.Down:
							g.DrawString(markLine.Marks[i3], Font, markLine.TextBrush, new RectangleF(points[i3].X - 100f, points[i3].Y + (float)HslMarkText.MarkTextOffect, 200f, Font.Height + 2), sf);
							break;
						}
					}
				}
				if (markLine.IsLineClosed)
				{
					g.DrawLines(markLine.LinePen, points);
					g.DrawLine(markLine.LinePen, points[0], points[points.Length - 1]);
				}
				else
				{
					g.DrawLines(markLine.LinePen, points);
				}
			}
			foreach (HslCurveItem line2 in data_dicts.Values)
			{
				if (!line2.Visible || !line2.LineRenderVisiable)
				{
					continue;
				}
				float[] data2 = line2.Data;
				if (data2 == null || data2.Length <= 1)
				{
					continue;
				}
				List<PointF> listPoints = new List<PointF>(line2.Data.Length);
				for (int i2 = 0; i2 < line2.Data.Length; i2++)
				{
					if (!float.IsNaN(line2.Data[i2]))
					{
						PointF point = default(PointF);
						point.X = (float)i2 * data_Scale_Render;
						point.Y = HslHelper.ComputePaintLocationY(line2.IsLeftFrame ? value_max_left : value_max_right, line2.IsLeftFrame ? value_min_left : value_min_right, panel1.Height - 60, line2.Data[i2]) + 20f;
						listPoints.Add(point);
					}
					else
					{
						HslCurve.DrawLineCore(g, line2, listPoints, pointsRadius);
						listPoints.Clear();
					}
				}
				HslCurve.DrawLineCore(g, line2, listPoints, pointsRadius);
			}
			for (int n = 0; n < markForeSections.Count; n++)
			{
				DrawMarkForeSection(g, markForeSections[n], Font);
			}
		}

		private void PictureBox3_MouseEnter(object sender, EventArgs e)
		{
			is_mouse_on_picture = true;
		}

		private void PictureBox3_MouseLeave(object sender, EventArgs e)
		{
			if (!isMouseFreeze)
			{
				is_mouse_on_picture = false;
			}
			this.onCurveMouseMove?.Invoke(this, -1, -1);
			pictureBox3.Invalidate();
		}

		private void PictureBox3_MouseDoubleClick(object sender, MouseEventArgs e)
		{
			if (isShowTextInfomation)
			{
				return;
			}
			isMouseFreeze = true;
			int index = Convert.ToInt32((float)((e.X >= 0) ? e.X : (65536 + e.X)) / data_Scale_Render);
			if (isRenderTimeData)
			{
				if (index >= 0 && index < data_times.Count)
				{
					this.onCurveDoubleClick?.Invoke(this, index, data_times[index]);
				}
			}
			else if (index >= 0 && index < data_customer.Count)
			{
				this.onCurveCustomerDoubleClick?.Invoke(this, index, data_customer[index]);
			}
		}

		private void PictureBox3_MouseUp(object sender, MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Left && isAllowSelectSection)
			{
				HslMarkForeSection markForeSection = new HslMarkForeSection
				{
					StartIndex = m_RowBetweenStart,
					EndIndex = m_RowBetweenEnd,
					Height = m_RowBetweenHeight,
					StartHeight = m_RowBetweenStartHeight,
					LinePen = markLinePen,
					FontBrush = markTextBrush
				};
				markForeSectionsTmp.Add(markForeSection);
				m_IsMouseLeftDown = false;
				pictureBox3.Invalidate();
				this.onCurveRangeSelect?.Invoke(this, m_RowBetweenStart, m_RowBetweenEnd);
				m_RowBetweenStart = -1;
				m_RowBetweenEnd = -1;
				m_RowBetweenHeight = -1;
				m_RowBetweenStartHeight = -1;
			}
		}

		private void PictureBox3_MouseDown(object sender, MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Right)
			{
				isMouseFreeze = false;
				markForeSectionsTmp.Clear();
				m_RowBetweenStart = -1;
				m_RowBetweenEnd = -1;
				m_RowBetweenHeight = -1;
				m_RowBetweenStartHeight = -1;
				pictureBox3.Invalidate();
			}
			else if (isAllowSelectSection)
			{
				m_IsMouseLeftDown = true;
				m_RowBetweenStart = Convert.ToInt32((float)((e.X >= 0) ? e.X : (65536 + e.X)) / data_Scale_Render);
				m_RowBetweenStartHeight = e.Y;
				m_RowBetweenHeight = e.Y;
			}
		}

		/// <summary>
		/// 强行设置曲线中活动的点信息，显示数值
		/// </summary>
		/// <param name="x">横坐标x</param>
		/// <param name="y">横坐标y</param>
		public void SetCurveMousePosition(int x, int y)
		{
			if (x < 0 || y < 0)
			{
				is_mouse_on_picture = false;
			}
			else
			{
				is_mouse_on_picture = true;
			}
			mouse_location.X = x;
			mouse_location.Y = y;
			pictureBox3.Invalidate();
		}

		private void PictureBox3_MouseMove(object sender, MouseEventArgs e)
		{
			if (is_mouse_on_picture && !isShowTextInfomation && !isMouseFreeze)
			{
				mouse_location = e.Location;
				if (mouse_location.X < 0)
				{
					mouse_location.X = 65536 + mouse_location.X;
				}
				this.onCurveMouseMove?.Invoke(this, mouse_location.X, mouse_location.Y);
				pictureBox3.Invalidate();
			}
		}

		private void PictureBox3_Paint(object sender, PaintEventArgs e)
		{
			Graphics g = e.Graphics;
			g.SmoothingMode = SmoothingMode.AntiAlias;
			g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
			Font font = new Font(Font.FontFamily, 12f);
			Brush brush = new SolidBrush(Color.FromArgb(220, Color.FromArgb(52, 52, 52)));
			int dataIndex = (int)((float)mouse_location.X / data_Scale_Render);
			for (int i = 0; i < markForeSectionsTmp.Count; i++)
			{
				DrawMarkForeSection(g, markForeSectionsTmp[i], font);
			}
			if (m_IsMouseLeftDown && m_RowBetweenStart != -1 && dataIndex < data_count)
			{
				m_RowBetweenEnd = Convert.ToInt32((float)mouse_location.X / data_Scale_Render);
				m_RowBetweenHeight = mouse_location.Y;
			}
			HslMarkForeSection markForeSection = new HslMarkForeSection
			{
				StartIndex = m_RowBetweenStart,
				EndIndex = m_RowBetweenEnd,
				Height = m_RowBetweenHeight,
				StartHeight = m_RowBetweenStartHeight,
				LinePen = markLinePen,
				FontBrush = markTextBrush
			};
			DrawMarkForeSection(g, markForeSection, font);
			for (int k = 0; k < markForeActiveSections.Count; k++)
			{
				if (dataIndex >= markForeActiveSections[k].StartIndex && dataIndex <= markForeActiveSections[k].EndIndex)
				{
					DrawMarkForeSection(g, markForeActiveSections[k], font);
				}
			}
			if (is_mouse_on_picture && !isShowTextInfomation)
			{
				g.DrawLine(moveLinePen, mouse_location.X, 15, mouse_location.X, panel1.Height - 38);
				if (dataIndex >= data_count || dataIndex < 0)
				{
					return;
				}
				int paint_y = mouse_location.Y - data_dicts.Count * 20 - 20;
				int tipBoxX = mouse_location.X;
				if (tipBoxX + 250 > panel1.Width + panel1.HorizontalScroll.Value)
				{
					tipBoxX = mouse_location.X - data_tip_width - 10;
				}
				Rectangle rect = new Rectangle(tipBoxX + 5, paint_y - 5, data_tip_width, data_dicts.Count * 20 + 10);
				g.FillRectangle(brush, rect);
				g.DrawRectangle(Pens.HotPink, rect);
				foreach (KeyValuePair<string, HslCurveItem> item3 in data_dicts)
				{
					Rectangle rec = new Rectangle(rect.X + 3, paint_y, data_tip_width - 6, 20);
					g.DrawString(item3.Key, font, Brushes.Cyan, rec, sf_left);
					if (dataIndex < item3.Value.Data.Length)
					{
						g.DrawString(string.Format(item3.Value.RenderFormat, item3.Value.Data[dataIndex]), font, Brushes.Cyan, rec, sf_right);
					}
					paint_y += 20;
				}
				paint_y = mouse_location.Y + 25;
				for (int j = 0; j < markForeActiveSections.Count; j++)
				{
					if (dataIndex < markForeActiveSections[j].StartIndex || dataIndex > markForeActiveSections[j].EndIndex)
					{
						continue;
					}
					float height = 0f;
					foreach (KeyValuePair<string, string> item2 in markForeActiveSections[j].CursorTexts)
					{
						height += g.MeasureString(item2.Key + " : " + item2.Value, Font, 244).Height + 8f;
					}
					rect = new Rectangle(tipBoxX + 5, paint_y - 5, 250, (int)height + 10);
					if (tipBoxX < mouse_location.X)
					{
						rect.X = mouse_location.X - 250 - 10;
					}
					g.FillRectangle(brush, rect);
					g.DrawRectangle(Pens.HotPink, rect);
					foreach (KeyValuePair<string, string> item in markForeActiveSections[j].CursorTexts)
					{
						height = g.MeasureString(item.Key + " : " + item.Value, Font, 244).Height;
						g.DrawString(layoutRectangle: new Rectangle(rect.X + 3, paint_y, 244, 200), s: item.Key + " : " + item.Value, font: font, brush: Brushes.Yellow, format: sf_default);
						paint_y += (int)height + 8;
					}
					break;
				}
				Rectangle rect_time = new Rectangle(mouse_location.X - 50, panel1.Height - 38, 100, 18);
				if (rect_time.X < panel1.HorizontalScroll.Value)
				{
					rect_time.X = panel1.HorizontalScroll.Value;
				}
				if (rect_time.X > panel1.HorizontalScroll.Value + panel1.Width - 101)
				{
					rect_time.X = panel1.HorizontalScroll.Value + panel1.Width - 101;
				}
				if (isRenderTimeData)
				{
					if (dataIndex < data_times.Count)
					{
						g.FillRectangle(brush, rect_time);
						g.DrawRectangle(Pens.HotPink, rect_time);
						g.DrawString(data_times[dataIndex].ToString(mouse_hover_time_formate), Font, Brushes.Cyan, rect_time, sf);
					}
				}
				else if (dataIndex < data_customer.Count)
				{
					g.FillRectangle(brush, rect_time);
					g.DrawRectangle(Pens.HotPink, rect_time);
					g.DrawString(data_customer[dataIndex], Font, Brushes.Cyan, rect_time, sf);
				}
			}
			font.Dispose();
			brush.Dispose();
		}

		/// <summary>
		/// 新增一段背景标识，用于隔离显示报警区段，特殊信息区段的数据
		/// </summary>
		/// <param name="markBackSection">背景标识层</param>
		public void AddMarkBackSection(HslMarkBackSection markBackSection)
		{
			markBackSections.Add(markBackSection);
		}

		/// <summary>
		/// 移除一个背景标识的内容，如果为null，则无效
		/// </summary>
		/// <param name="markBackSection">标记信息</param>
		public void RemoveMarkBackSection(HslMarkBackSection markBackSection)
		{
			markBackSections.Remove(markBackSection);
		}

		/// <summary>
		/// 移除所有的前置的辅助标记曲线区间
		/// </summary>
		public void RemoveAllMarkBackSection()
		{
			markBackSections.Clear();
		}

		/// <summary>
		/// 新增一段辅助标记区间的信息，将会绘制在背景图层。
		/// </summary>
		/// <param name="markForeSection">标记信息</param>
		public void AddMarkForeSection(HslMarkForeSection markForeSection)
		{
			markForeSections.Add(markForeSection);
		}

		/// <summary>
		/// 移除一段辅助标记区间的信息，如果为null，则无效
		/// </summary>
		/// <param name="markForeSection">标记信息</param>
		public void RemoveMarkForeSection(HslMarkForeSection markForeSection)
		{
			markForeSections.Remove(markForeSection);
		}

		/// <summary>
		/// 移除所有的前置的辅助标记曲线区间
		/// </summary>
		public void RemoveAllMarkForeSection()
		{
			markForeSections.Clear();
		}

		/// <summary>
		/// 移除所有的因为鼠标手动选择的辅助标记曲线区间
		/// </summary>
		public void RemoveAllMarkMouseSection()
		{
			markForeSectionsTmp.Clear();
			m_RowBetweenStart = -1;
			m_RowBetweenEnd = -1;
			m_RowBetweenHeight = -1;
			m_RowBetweenStartHeight = -1;
			pictureBox3.Invalidate();
		}

		/// <summary>
		/// 新增一段辅助标记的区间信息，将在鼠标光标移动的时候显示出数据信息，可用来标记一个产品的额外的信息内容，比如条码，生产信息
		/// </summary>
		/// <param name="markActiveSection">额外的活动的内容</param>
		public void AddMarkActiveSection(HslMarkForeSection markActiveSection)
		{
			markForeActiveSections.Add(markActiveSection);
		}

		private void DrawMarkForeSection(Graphics g, HslMarkForeSection markForeSection, Font font)
		{
			if (markForeSection == null)
			{
				return;
			}
			float m_LocationY = (markForeSection.Height > 1f) ? markForeSection.Height : ((float)(panel1.Height - 60) * markForeSection.Height + 20f);
			float m_Location_Start_Y = (markForeSection.StartHeight > 1f) ? markForeSection.StartHeight : ((float)(panel1.Height - 60) * markForeSection.StartHeight + 20f);
			if (markForeSection.StartIndex == -1 || markForeSection.EndIndex == -1 || markForeSection.EndIndex <= markForeSection.StartIndex || !(m_Location_Start_Y < m_LocationY))
			{
				return;
			}
			int paint_start_index = Convert.ToInt32((float)markForeSection.StartIndex * data_Scale_Render);
			int paint_end_index = Convert.ToInt32((float)markForeSection.EndIndex * data_Scale_Render);
			if (markForeSection.StartIndex < data_count && markForeSection.EndIndex < data_count && markForeSection.StartIndex < data_times.Count && markForeSection.EndIndex < data_times.Count)
			{
				g.DrawLine(markForeSection.LinePen, new PointF(paint_start_index, m_Location_Start_Y), new PointF(paint_start_index, m_LocationY + 30f));
				g.DrawLine(markForeSection.LinePen, new PointF(paint_end_index, m_Location_Start_Y), new PointF(paint_end_index, m_LocationY + 30f));
				int Offect = markForeSection.IsRenderTimeText ? 20 : 0;
				int leftOffect = (paint_end_index - paint_start_index > 100) ? Offect : 110;
				int textPosition_Lengh = paint_end_index - paint_start_index;
				g.DrawLine(markForeSection.LinePen, new PointF(paint_start_index - leftOffect, m_LocationY), new PointF(paint_end_index + Offect, m_LocationY));
				g.DrawLines(markForeSection.LinePen, new PointF[3]
				{
					new PointF(paint_start_index + 20, m_LocationY + 10f),
					new PointF(paint_start_index, m_LocationY),
					new PointF(paint_start_index + 20, m_LocationY - 10f)
				});
				g.DrawLines(markForeSection.LinePen, new PointF[3]
				{
					new PointF(paint_end_index - 20, m_LocationY - 10f),
					new PointF(paint_end_index, m_LocationY),
					new PointF(paint_end_index - 20, m_LocationY + 10f)
				});
				TimeSpan sptime = data_times[markForeSection.EndIndex] - data_times[markForeSection.StartIndex];
				if (paint_end_index - paint_start_index <= 100)
				{
					g.DrawString(sptime.TotalMinutes.ToString("F1") + " 分钟", font, markForeSection.FontBrush, new PointF(paint_start_index - 100, m_LocationY - 17f));
				}
				else
				{
					g.DrawString(sptime.TotalMinutes.ToString("F1") + " 分钟", font, markForeSection.FontBrush, new RectangleF(paint_start_index, m_LocationY - (float)font.Height - 2f, paint_end_index - paint_start_index, font.Height), sf);
				}
				if (!string.IsNullOrEmpty(markForeSection.MarkText))
				{
					g.DrawString(markForeSection.MarkText, font, markForeSection.FontBrush, new RectangleF(paint_start_index, m_LocationY + 3f, paint_end_index - paint_start_index, font.Height), sf);
				}
				if (markForeSection.IsRenderTimeText)
				{
					g.DrawString("开始:" + data_times[markForeSection.StartIndex].ToString(data_time_formate), font, markForeSection.FontBrush, new PointF(paint_end_index + 5, m_LocationY - 17f));
					g.DrawString("结束:" + data_times[markForeSection.EndIndex].ToString(data_time_formate), font, markForeSection.FontBrush, new PointF(paint_end_index + 5, m_LocationY + 2f));
				}
			}
		}

		/// <summary>
		/// 将当前的图形曲线保存为图片内容，可用于存储本地的文件，或是打印到纸张，默认大小为控件的大小
		/// </summary>
		/// <returns>图片内容</returns>
		public Bitmap SaveToBitmap()
		{
			if (isShowTextInfomation)
			{
				Bitmap bitmap = new Bitmap(base.Width, base.Height);
				Graphics g = Graphics.FromImage(bitmap);
				g.SmoothingMode = SmoothingMode.AntiAlias;
				g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
				g.Clear(backColor);
				PaintMain(g, base.Width, base.Height);
				g.TranslateTransform(43f, 29f);
				int m_width = (panel1.Width <= 10) ? 1 : panel1.Width;
				int m_height2 = (panel1.Height > 10) ? panel1.Height : 10;
				PaintFromString(g, Text, m_width, m_height2);
				g.TranslateTransform(-43f, -29f);
				g.Dispose();
				return bitmap;
			}
			Bitmap bitmap2 = new Bitmap(pictureBox3.Width + 86, base.Height);
			Graphics g2 = Graphics.FromImage(bitmap2);
			g2.SmoothingMode = SmoothingMode.AntiAlias;
			g2.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
			g2.Clear(backColor);
			DrawCoordinate(g2, isLeft: true, 3f, 29f, value_max_left, value_min_left, sf_right, value_unit_left);
			if (isRederRightCoordinate)
			{
				DrawCoordinate(g2, isLeft: false, bitmap2.Width - 43, 29f, value_max_right, value_min_right, sf_left, value_unit_right);
			}
			PaintHeadText(g2);
			int m_width2 = (int)((float)data_count * data_Scale_Render) + 200;
			if (m_width2 < panel1.Width)
			{
				m_width2 = panel1.Width;
			}
			int m_height = panel1.Height - 18;
			if (m_height < 10)
			{
				m_height = 10;
			}
			g2.TranslateTransform(43f, 29f);
			GetRenderCurveMain(g2, m_width2, m_height);
			g2.TranslateTransform(-43f, -29f);
			g2.Dispose();
			return bitmap2;
		}

		/// <summary> 
		/// 清理所有正在使用的资源。
		/// </summary>
		/// <param name="disposing">如果应释放托管资源，为 true；否则为 false。</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		/// <summary> 
		/// 设计器支持所需的方法 - 不要修改
		/// 使用代码编辑器修改此方法的内容。
		/// </summary>
		private void InitializeComponent()
		{
			pictureBox3 = new System.Windows.Forms.PictureBox();
			panel1 = new System.Windows.Forms.Panel();
			((System.ComponentModel.ISupportInitialize)pictureBox3).BeginInit();
			panel1.SuspendLayout();
			SuspendLayout();
			pictureBox3.Location = new System.Drawing.Point(0, 0);
			pictureBox3.Name = "pictureBox3";
			pictureBox3.Size = new System.Drawing.Size(351, 209);
			pictureBox3.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
			pictureBox3.TabIndex = 2;
			pictureBox3.TabStop = false;
			panel1.Anchor = (System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right);
			panel1.AutoScroll = true;
			panel1.BackColor = System.Drawing.Color.Transparent;
			panel1.Controls.Add(pictureBox3);
			panel1.Location = new System.Drawing.Point(43, 29);
			panel1.Name = "panel1";
			panel1.Size = new System.Drawing.Size(766, 446);
			panel1.TabIndex = 3;
			base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
			BackColor = System.Drawing.Color.FromArgb(46, 46, 46);
			base.Controls.Add(panel1);
			base.Name = "HslCurveHistory";
			base.Size = new System.Drawing.Size(852, 478);
			base.Load += new System.EventHandler(HslCurveHistory_Load);
			base.SizeChanged += new System.EventHandler(HslCurveHistory_SizeChanged);
			((System.ComponentModel.ISupportInitialize)pictureBox3).EndInit();
			panel1.ResumeLayout(false);
			panel1.PerformLayout();
			ResumeLayout(false);
		}
	}
}
